using System.IO;
using System.Collections;
using System.Collections.Generic;
using LS.UnityExtensions;
using LS.UnityExtensions.Editor;
using UnityEngine;
using UnityEditor;
using UnityGameFramework.Editor;
using UnityEditorInternal;

namespace LS.Editor
{
    public class ProjectPreparerMenu
    {
        [MenuItem("Lancer Studio/Prepare/Prepare Project Files")]
        public static void PreparerProjectFiles()
        {
            PreparEditorDirectorys();
            string dataTableGeneratingPath = $"{LSPath.LSAssetsDirectoryName}/{LSPath.LSDataTablesAssetPath}";
            CreateScriptableObjectFile<DataTableGeneratingCollection>(dataTableGeneratingPath, nameof(DataTableGeneratingCollection));

            string configPath = $"{LSPath.LSAssetsDirectoryName}/{LSPath.LSConfigAssetPath}";
            CreateConfigFile(configPath, "DefaultConfig");
            CreateConfigFile(configPath, "DefaultLocalization");
            SetupAssemblyDefinition();
        }

        [MenuItem("Lancer Studio/Prepare/Prepare Project Directorys")]
        public static void PreparProjectDirectory()
        {
            string dataPath = Application.dataPath;
            Debug.Log($"log data path: {dataPath}");
            PreparRuntimeDirectorys();
            PreparEditorDirectorys();
        }

        [MenuItem("Lancer Studio/Prepare/Prepare Runtime Asset Directorys")]
        public static void PreparRuntimeDirectorys()
        {
            string dataPath = Application.dataPath;
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSRuntimeScriptsPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSConfigAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSDataTablesAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSEntityAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSFontsAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSLocalizationAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSMusicAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSUIAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSUISoundAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSUIIconsAssetPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSScenesAssetPath}");

            AssetDatabase.Refresh();
        }

        [MenuItem("Lancer Studio/Prepare/Prepare Editor Asset Directorys")]
        public static void PreparEditorDirectorys()
        {
            string dataPath = Application.dataPath;
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSEditorAssetsPath}");
            LSPathEditor.CreateDirectoryWithoutExisted($"{dataPath}/{LSPath.LSEditorScriptsPath}");
            AssetDatabase.Refresh();
        }

        public static void CreateScriptableObjectFile<T>(string directory,string fileName)where T: ScriptableObject
        {
            string path = $"{directory}/{fileName}.asset";
            if (File.Exists(path))
            {
                Debug.LogWarning($"File with path {path} Already Exist!");
                return;
            }
            T so = ScriptableObject.CreateInstance<T>();
            LSPathEditor.CreateDirectoryWithoutExisted(directory);
            AssetDatabase.CreateAsset(so, $"{directory}/{fileName}.asset");
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            Debug.Log($"File with path {path} Created!");
        }

        public static void CreateConfigFile(string directory,string fileName)
        {
            string path = $"{directory}/{fileName}.csv";
            if (File.Exists(path))
            {
                Debug.LogWarning($"File with path {path} Already Exist!");
                return;
            }
            ConfigMenu.CreateCustomConfig(path);
            Debug.Log($"File with path {path} Created!");
        }
        
        public static void CreateDictionaryFile(string directory,string fileName)
        {
            string path = $"{directory}/{fileName}.xml";
            if (File.Exists(path))
            {
                Debug.LogWarning($"File with path {path} Already Exist!");
                return;
            }
            LocalizationSettingUtil.CreateDirectory(path);
            Debug.Log($"File with path {path} Created!");
        }
        
        private static void SetupAssemblyDefinition()
        {
            var uextensionSetting = UnityExtensionsEditorConfig.Instance;
            var setting = GameFrameworkSettings.SettingObject;
            if (setting == null)
            {
                setting = ScriptableObject.CreateInstance<GameFrameworkSettings>();
                GameFrameworkSettings.SettingObject = setting;
            }
            var editorAssemblyGUIDs = AssetDatabase.FindAssets($"t:{nameof(AssemblyDefinitionAsset)}",
                new string[] {
                    "Assets/ls-framework/Editor/Scripts",
                    "Assets/com.lancerstudio.lsframework/Editor/Scripts",
                    "Packages/ls-framework/Editor/Scripts",
                    "Packages/com.lancerstudio.lsframework/Editor/Scripts",
                });
            
            for (int i = 0; i < editorAssemblyGUIDs.Length; i++)
            {
                string guid = editorAssemblyGUIDs[i];
                string path = AssetDatabase.GUIDToAssetPath(guid);
                var asset = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(path);
                if (!setting.EditorSearchedScopeDefinitions.Contains(asset))
                {
                    setting.EditorSearchedScopeDefinitions.Add(asset);
                }

                if (!uextensionSetting.EditorSearchedScopeDefinitions.Contains(asset))
                {
                    uextensionSetting.EditorSearchedScopeDefinitions.Add(asset);
                }
            }

            var runtimeAssemblyGUIDs = AssetDatabase.FindAssets($"t:{nameof(AssemblyDefinitionAsset)}",
                new string[] {
                    "Assets/ls-framework/Runtime/Scripts",
                    "Assets/com.lancerstudio.lsframework/Runtime/Scripts",
                    "Packages/ls-framework/Runtime/Scripts",
                    "Packages/com.lancerstudio.lsframework/Runtime/Scripts",
                });

            for (int i = 0; i < runtimeAssemblyGUIDs.Length; i++)
            {
                string guid = runtimeAssemblyGUIDs[i];
                string path = AssetDatabase.GUIDToAssetPath(guid);
                var asset = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(path);
                if (!setting.RuntimeSearchedScopeDefinitions.Contains(asset))
                {
                    setting.RuntimeSearchedScopeDefinitions.Add(asset);
                }
                if (!uextensionSetting.RuntimeSearchedScopeDefinitions.Contains(asset))
                {
                    uextensionSetting.RuntimeSearchedScopeDefinitions.Add(asset);
                }
            }

            GameFrameworkSettings.Save();
            uextensionSetting.Save();
        }
    }
}
